var interval;
var active = 1;
var result_notes = [];
var result_rythms = [];
var answer_notes = [1, 3, 2, 1, 2, 1, 1];
var answer_rythms = [0, 8, 0, 0, 0, 0, 8];
var Score;
var passphrase = "<span>To</span><span class=\"hyphened\">day</span><span> Was</span><span> A</span><span> Fair</span><span class=\"hyphened\">y</span><span class=\"hyphened\">tale</span>";

function sq(num) {
    return num*num;
}

function draw_note(note, rythm, x) {
    Score.strokeStyle = "white";
    // If the note is half-note...
    if ( rythm == 2 ) {
        Score.fillStyle = "white";
    } else {
        Score.fillStyle = "black";
    }
    if ( note == 0 ) {
        // If the note is 1/16 of a whole
        note = 9;
    } else {
        note -= 1;
    }
    Score.beginPath();
    y = 240 - 20*note
    switch ( rythm ) {
        case 0: Score.moveTo(x+18, y-80);
                Score.lineTo(x+39, y-20);
        case 8: Score.moveTo(x+18, y-120);
                Score.lineTo(x+39, y-60);
        case 2:
        case 4: Score.moveTo(x+18, y);
                Score.lineTo(x+18, y-120);
    }
    Score.arc(x, y, 18, 0, Math.PI*2, true);
    if ( note == 0 ) {
        Score.moveTo(x-40, y);
        Score.lineTo(x-18, y);
        Score.moveTo(x+18, y);
        Score.lineTo(x+40, y);
    }
    Score.fill();
    Score.stroke();
    Score.closePath();
}

function draw_sequence(notes, rythms, offset, step) {
    var index = 0;
    while ( index < notes.length ) {
        draw_note(notes[index], rythms[index], offset+step*index);
        index += 1;
    }
}

function clicked_note(notes, rythms, offset, step, x, y) {
    // See what note was clicked
    var index = 0;
    while ( index < notes.length ) {
        k = 240 - 20*notes[index];
        h = offset + step*index;
        // Use circle equation to see which note is clicked
        if ( sq(x-h) + sq(y-k) <= sq(18) ) {
            return [notes[index], rythms[index]];
        }
        index += 1;
    }
    return [null, null];
}

function draw_tune() {
    draw_score();
    draw_sequence([1, 2, 3, 2, 1, 2, 1, 1], [0, 8, 8, 0, 0, 0, 0, 8], 125, 60, Score);
}

function choose_note(event) {
    // Note choosing process
    if ( event.type == "keypress" ) {
        $("canvas").unbind("click");
        note = event.which - 48;
        if ( note < 0  || note > 9 ) {
            $("canvas").one("click", choose_note);
            $(document).one("keypress", choose_note);
            draw_notes();
            return event;
        }
    } else {
        $(document).unbind("keypress");
        offset = $("canvas").offset();
        x = event.pageX - offset.left;
        y = event.pageY - offset.top;
        note = clicked_note([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 125, 50, x, y)[0];
        if ( note == null ) {
            $("canvas").one("click", choose_note);
            $(document).one("keypress", choose_note);
            draw_notes();
            return event;
        }
    }
    draw_score();
    $("fieldset span:nth-of-type(" + String(active) + ")").toggleClass("active");
    result_notes[result_notes.length] = note;
    if ( active == $("fieldset span").size() ) {
        if ( result_notes == answer_notes && result_rythms == answer_rythms ) {
            draw_tune();
        }
        else {
            active = 1;
            result_notes = [];
            result_rythms = [];
            choose();
        }
    } else {
        active += 1;
        choose();
    }
    return event;
}

function choose_rythm(event) {
    // Finding what rythm has been chosen
    if ( event.type == "keypress" ) {
        // Unbind the unused event
        $("canvas").unbind("click");
        // Get the correct number (fast way)
        // The input is always supposed to be a number from the set {0, 1, 2, 4, 8}
        // If it is not, then the choosing is not done and the user goes back to the choosing step
        rythm = event.which - 48;
        switch ( rythm ) {
            case 0:
            case 1:
            case 2:
            case 4:
            case 8:
                break;
            default:
                $("canvas").one("click", choose_rythm);
                $(document).one("keypress", choose_rythm);
                draw_rythms();
                return event;
        }
    } else {
        // Unbind the unused event
        $(document).unbind("keypress");
        // Get the offset of the canvas element
        offset = $("canvas").offset();
        // Get the x and y position of the click inside the canvas
        x = event.pageX - offset.left;
        y = event.pageY - offset.top;
        // Get the note that was clicked
        rythm = clicked_note([4, 5, 4, 5, 4], [1, 2, 4, 8, 0], 175, 75, x, y)[1];
        if ( rythm == null ) {
            // If no note was clicked, the user is sent back to choosing
            $("canvas").one("click", choose_rythm);
            $(document).one("keypress", choose_rythm);
            draw_rythms();
            return event;
        }
    }
    // If a note was clicked, the user is sent to the note choosing process
    draw_notes();
    $("canvas").one("click", choose_note);
    $(document).one("keypress", choose_note);
    result_rythms[result_rythms.length] = rythm;
    return event;
}

function choose() {
    // Put emphasis on the appropriate lyrical step
    $("fieldset span:nth-of-type(" + String(active) + ")").toggleClass("active");
    // Display the rythms from which to choose
    draw_rythms();
    // Bind keypress and click events to checking the chosen rythm
    $("canvas").one("click", choose_rythm);
    $(document).one("keypress", choose_rythm);
}

function is_right(password) {
    // Check if the entered song title is the right one
    if ( password == "Today Was A Fairytale") {
        $("fieldset").fadeOut("slow",
            function () {
                // Get the lyrics to appear
                $(this).html(passphrase).fadeIn("slow");
                // Start the chossing process
                choose();
            }
        );
    }
}

function draw_score() { 
    // Clear the canvas and ensure the settings are correct
    Score.clearRect(0, 0, 600, 260);
    Score.strokeStyle = "white";
    Score.globalAlpha = 1.0;
    Score.lineWidth = 2;
    // Draw the lines of the musical score
    Score.beginPath();
    var i = 1
    while ( i <= 5) {
        Score.moveTo(0, 40*i);
        Score.lineTo(600, 40*i);
        i += 1;
    }
    Score.stroke()
    Score.closePath();
    Score.lineWidth = 3;
    // Draw the key of the score
    Score.beginPath();
    Score.arc(50, (40*5)+30, 10, 3*Math.PI/2, Math.PI*2, true);
    Score.lineTo(60, 20);
    Score.stroke();
    Score.closePath();
    Score.beginPath();
    Score.arc(70, 20, 10, Math.PI/4, Math.PI, true);
    var offset = 10 * Math.sqrt(2)/2;
    Score.moveTo(70+offset, 20+offset);
    Score.lineTo(10+offset, 120+offset);
    Score.stroke();
    Score.closePath();
    Score.beginPath();
    Score.arc(59, 155, 50, Math.sqrt(2)/2 + Math.PI, Math.PI*2, true);
    Score.stroke();
    Score.closePath();
    Score.beginPath();
    Score.arc(74, 155, 35, 0, Math.PI, true);
    Score.stroke();
    Score.closePath();
}

function draw_rythms() {
    // Draw the musical rythms available to choose from the score.
    // This function displays only rythms, not the notes
    draw_score();
    draw_sequence([4, 5, 4, 5, 4], [1, 2, 4, 8, 0], 175, 75);
    
}

function draw_notes() {
    // Draw the musical notes available to choose from on the score.
    // This function displays only notes, not the rythms.
    draw_score();
    draw_sequence([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 125, 50);
}

function Main() {
    // Setting the canvas used through the whole script
    Score = document.getElementById("portée").getContext("2d");
    // Placing the text entry field in its place
    $("fieldset").html("<input placeholder=\"It's your ringsong.\" value=\"\"/>");
    // Ensuring that the value will be checked as soon as it is entered
    $("input").keyup( function (event) { is_right(this.value); } );
    // Draw the base musical score, to hint for what comes next.
    draw_score();
}

$(document).ready( function () {
    Main();
});